package com.sk.sk_frame_cloud.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.sk.sk_frame_cloud.config.DynamicDataSourceConfig;
import com.sk.sk_frame_cloud.config.DynamicDataSourceHolder;
import com.sk.sk_frame_cloud.entity.DataSourceInfo;
import com.sk.sk_frame_cloud.service.ISysProManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;
import java.util.Objects;

/**
 * @Author jiaok
 * @Date 2023-12-12 10:11
 */
@Slf4j
@Component
public class DataSourceUtil {

    @Value("${initPro.sqlPath}")
    private String initSqlPath;
    @Resource
    private DynamicDataSourceConfig dynamicDataSourceConfig;

    /**
     * 获取当前正在操作的数据源
     * @return
     */
    public  DruidDataSource getCurrentDataSource() {
        return  (DruidDataSource) dynamicDataSourceConfig.getDefineTargetDataSources().get(DynamicDataSourceHolder.getDynamicDataSourceKey());
    }


    public void  initDatabase(String databaseName, DataSourceInfo dataSourceInfo) throws SQLException, IOException {
        //当前正在操作的数据源
        DruidDataSource currentDataSource = this.getCurrentDataSource();
        //创建对应的数据库
        SqlFileUtil.createDatabase(currentDataSource.getConnection(),databaseName);
        log.info("===========================  准备切换数据源  ===========================");
        DruidDataSource dataSourceConnection = this.createDataSourceConnection(dataSourceInfo);
        if (Objects.nonNull(dataSourceConnection)) {
            //将新的数据源连接追加到目标数据源中
            this.addDynamicDataSource(databaseName, dataSourceConnection);
            //设置当前线程数据源名称
            DynamicDataSourceHolder.setDynamicDataSourceKey(databaseName);
            DruidDataSource newSource = (DruidDataSource) dynamicDataSourceConfig.getDefineTargetDataSources()
                    .get(DynamicDataSourceHolder.getDynamicDataSourceKey());
            SqlFileUtil.executeSqlFile(newSource.getConnection(),initSqlPath);
        }
    }



    /**
     * 根据传入信息，动态添加数据源
     * @return
     */
    public DruidDataSource createDataSourceConnection(DataSourceInfo dataSourceInfo){

        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(dataSourceInfo.getUrl());
        druidDataSource.setUsername(dataSourceInfo.getUserName());
        druidDataSource.setPassword(dataSourceInfo.getPassword());
        druidDataSource.setBreakAfterAcquireFailure(true);
        druidDataSource.setConnectionErrorRetryAttempts(0);
        try {
            DruidPooledConnection connection = druidDataSource.getConnection(2000);
            log.info("=========================== 数据源 {} 连接成功 ，用户名 {} , 密码 {} ===========================",
                    dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
            return druidDataSource;
        } catch (SQLException e) {
            log.error("=========================== 数据源 {} 连接失败 ，用户名 {} , 密码 {} ===========================",
                    dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
            throw new RuntimeException(e);
        }
    }


    /**
     * 将新增的数据源追加到内存中
     * @param druidDataSource 数据源信息
     * @param sourceName 数据源名称
     */
    public void addDynamicDataSource(String sourceName,DruidDataSource druidDataSource){
        Map<Object, Object> defineTargetDataSources = dynamicDataSourceConfig.getDefineTargetDataSources();
        defineTargetDataSources.put(sourceName,druidDataSource);
        //重置数据源集
        dynamicDataSourceConfig.setTargetDataSources(defineTargetDataSources);
        dynamicDataSourceConfig.afterPropertiesSet();
    }

}
